package com.bracketbird.client.gui.club.tournament;

import com.bracketbird.client.*;
import com.bracketbird.client.gui.club.tournament.rtc.*;
import com.bracketbird.client.model.*;
import com.bracketbird.client.model.keys.*;
import com.bracketbird.client.model.tournament.*;
import com.bracketbird.client.util.*;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.logical.shared.*;
import com.google.gwt.user.client.ui.*;
import com.bracketbird.clientcore.gui.*;
import com.bracketbird.clientcore.style.*;
import com.bracketbird.clientcore.util.*;

import java.util.*;

/**
 *
 */
public class PlayingTeamComponent extends FocusComponent {

    private boolean allowNonMembers = false;
    private List<PlayerComponent> players = new ArrayList<PlayerComponent>();
    public SuggestBoxComponent suggestBox;
    private StringToMember stringToMembers;
    private SimplePanelComponent suggestBoxHolder;
    private VerticalComponent playersPanel;
    private LabelTextBoxComponent teamName;
    private TextAreaComponent infoArea;
    private HorizontalComponent colOne;
    private HorizontalComponent colTwo;
    private HorizontalComponent colThree;
    private HorizontalComponent colFour;
    private Layout17 suggestBoxLayout = new TextLayout("15px", "100%", Vertical.MIDDLE).sizeSmall().colorBaseDark().add(P.VERTICAL_ALIGN_MIDDLE);

    private FocusManager focusManager;
    private LabelTextBoxComponent seeding;
    private PlayingTeam playingTeam;

    private TournamentListener<TournamentTeamEvent> teamUpdatedListener = new TournamentListener<TournamentTeamEvent>() {
        public void onChange(TournamentTeamEvent event) {
            if (event.getAction().equals(TournamentTeamEvent.Action.update)) {
                updateTeam(event.getTeam());
            }
        }
    };


    public PlayingTeamComponent(PlayingTeam t, FocusManager fm, final Participaters parent, StringToMember stm, boolean allowNonMembers) {
        super();
        this.playingTeam = t;
        this.focusManager = fm;
        this.stringToMembers = stm;
        this.allowNonMembers = allowNonMembers;

        this.playingTeam.addTeamsListener(teamUpdatedListener);
        HorizontalComponent content = new HorizontalComponent();
        add(content);

        //setting up focusmanager

        focusManager.addChild(getTeamName());
        focusManager.addChild(getSuggestBox());
        focusManager.addChild(getSeeding());
        focusManager.addChild(getInfoArea());


        content.add(getColOne(), new TextLayout(null, parent.COL_ONE_LENGTH));
        content.add(getColTwo(), new TextLayout(null, parent.COL_TWO_LENGTH));
        content.add(getColThree(), new TextLayout(null, parent.COL_THREE_LENGTH));
        content.add(getColFour(), new TextLayout(-2, 0, 8, 0, null, parent.COL_FOUR_LENGTH));


        getSuggestBox().setFocus(false);
        //fManager.add(getSu);

        getPanel().addFocusHandler(new FocusHandler() {
            public void onFocus(FocusEvent event) {
                getSuggestBox().setFocus(true);
            }
        });

        ApplicationController.scrollDown();


    }


    public void updateMembersSuggestList() {
        SuggestBoxComponent oldSuggestBox = suggestBox;
        suggestBox = createSuggestBox();
        getSuggestBoxHolder().add(suggestBox, suggestBoxLayout);
        focusManager.replace(oldSuggestBox, suggestBox);
        suggestBox.setFocus(true);
    }


    private SuggestBoxComponent createSuggestBox() {
        MultiWordSuggestOracle or = new MultiWordSuggestOracle();
        for (final String name : stringToMembers.getStringToMemberMap().keySet()) {
            or.add(name);
        }
        SuggestBoxComponent sbc = new SuggestBoxComponent(or);
        initSuggestionBox(sbc);

        return sbc;
    }

    public SuggestBoxComponent getSuggestBox() {
        if (suggestBox == null) {
            suggestBox = createSuggestBox();
        }
        return suggestBox;
    }

    private void initSuggestionBox(final SuggestBoxComponent sbc) {
        sbc.getSuggestBox().addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
            public void onSelection(SelectionEvent<SuggestOracle.Suggestion> event) {
                String mString = event.getSelectedItem().getReplacementString();
                Member m = stringToMembers.getStringToMemberMap().get(mString);
                if (m != null) {
                    addNewPlayer(m, mString);
                    sbc.getSuggestBox().setText("");
                }
            }
        });
        sbc.addKeyDownHandler(new KeyDownHandler() {
            public void onKeyDown(KeyDownEvent event) {
                TeamsPageController.getInstance().hidePopups();

                int keyCode = event.getNativeKeyCode();
                String mString = sbc.getSuggestBox().getText();
                if (keyCode == KeyUtil.ENTER && (mString == null || mString.equals(""))) {
                    if (!players.isEmpty()) {
                        focusManager.onKeyDown(new FocusKeyDownEvent(sbc, KeyUtil.DOWN_ARROW));
                    }
                }
                if (allowNonMembers) {
                    if (mString == null || mString.equals("")) {
                        //ignore
                    }
                    else if (KeyUtil.isEnter(keyCode)) {
                        addNewPlayer(null, mString + " (not member)");
                        sbc.getSuggestBox().setText("");
                    }
                    else if (sbc.isLeavable(keyCode)) {
                        addNewPlayer(null, mString + " (not member)");
                        sbc.getSuggestBox().setText("");
                    }
                }

            }
        });


        sbc.getSuggestBox().setLimit(15);
    }

    public HorizontalComponent getColOne() {
        if (colOne == null) {
            colOne = new HorizontalComponent();

            HorizontalComponent hc = new HorizontalComponent();
            ImageComponent minus = new ImageComponent("deleteSmall.png");
            minus.setTitle("Delete team");
            minus.getImage().addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    RTC.getInstance().deleteTeam(playingTeam, true);
                }
            });

            minus.getImage().addMouseOverHandler(MouseOver.POINTER);
            hc.add(getTeamName(), new TextLayout(Horizontal.LEFT, Vertical.MIDDLE).sizeSmall().colorBaseDark().noWrap());
            hc.add(minus, new TextLayout(2, 0, 0, 10, Horizontal.LEFT, Vertical.MIDDLE));

            colOne.add(hc, new TextLayout(Horizontal.LEFT, Vertical.TOP));
        }
        return colOne;
    }

    public HorizontalComponent getColTwo() {
        if (colTwo == null) {
            colTwo = new HorizontalComponent();
            VerticalComponent pv = new VerticalComponent();
            pv.add(getPlayersPanel(), new TextLayout(null, "100%", Horizontal.LEFT, Vertical.TOP).noWrap());
            pv.add(getSuggestBoxHolder(), new TextLayout(null, "125px", Horizontal.LEFT, Vertical.TOP));
            colTwo.add(pv, new TextLayout(Horizontal.LEFT, Vertical.TOP));

        }
        return colTwo;
    }

    public HorizontalComponent getColThree() {
        if (colThree == null) {
            colThree = new HorizontalComponent();
            colThree.add(getSeeding(), new TextLayout(Horizontal.LEFT, Vertical.TOP).sizeSmall().colorBaseDark());
        }
        return colThree;
    }

    public LabelTextBoxComponent getSeeding() {
        if (seeding == null) {
            seeding = new LabelTextBoxComponent();
            seeding.setWidth("30px");
            seeding.setHeight("15px");

            seeding.getTextBox().getTextBox().addValueChangeHandler(new ValueChangeHandler<String>() {
                public void onValueChange(ValueChangeEvent<String> stringValueChangeEvent) {
                    try {
                        Integer value = StringUtil.isEmpty(stringValueChangeEvent.getValue()) ? null : Integer.valueOf(stringValueChangeEvent.getValue());
                        PlayingTeamVO upt = new PlayingTeamVO(playingTeam);
                        upt.setSeeding(value);
                        RTC.getInstance().updateTeam(playingTeam, upt, true);
                        //Service.updateTeam();
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        return seeding;
    }

    public HorizontalComponent getColFour() {
        if (colFour == null) {
            colFour = new HorizontalComponent();
            colFour.add(getInfoArea(), new TextLayout(null, "100%", Horizontal.RIGHT, Vertical.MIDDLE).sizeSmall().colorBaseDark().border(0));
            colFour.add(new LabelComponent(""), new TextLayout(null, "5px"));

        }
        return colFour;
    }


    public void refresh(PlayingTeam pt){
        updateTeam(pt);
    }

    private void updateTeam(PlayingTeam team) {
        //remove previous

        for (PlayerComponent p : players) {
            p.removeFromParent();
        }
        players = new ArrayList<PlayerComponent>();
        //

        for (MemberId memberId : team.getMembers()) {
            Member m = UserManager.getInstance().getMember(memberId);
            addNewPlayerComponent(m, m.getLongName());
        }
        for (String name : team.getNonMembers()) {
            addNewPlayerComponent(null, name);
        }

        if(PlayingTeam.isTeamNameValid(team.getTeamName())){
            getTeamName().setText(team.getTeamName());
        }
        getInfoArea().setText(team.getInfo());
        getSeeding().setText(team.getSeeding() == null ? "" : (""+team.getSeeding()));

        adjustCommentSize();

    }

    public TextAreaComponent getInfoArea() {
        if (infoArea == null) {
            infoArea = new TextAreaComponent();
            infoArea.getTextArea().setVisibleLines(1);
            infoArea.getTextArea().addValueChangeHandler(new ValueChangeHandler<String>() {
                public void onValueChange(ValueChangeEvent<String> event) {
                    PlayingTeamVO upt = new PlayingTeamVO(playingTeam);
                    upt.setInfo(event.getValue());
                    RTC.getInstance().updateTeam(playingTeam, upt, true);
                }
            });
        }
        return infoArea;
    }


    public LabelTextBoxComponent getTeamName() {
        if (teamName == null) {
            teamName = new LabelTextBoxComponent();
            teamName.getTextBox().getTextBox().addValueChangeHandler(new ValueChangeHandler<String>() {
                public void onValueChange(ValueChangeEvent<String> e) {
                    if(PlayingTeam.isTeamNameValid(e.getValue())){
                        PlayingTeamVO vo = getPlayingTeam().createVO();
                        vo.setTeamName(e.getValue());
                        RTC.getInstance().updateTeam(getPlayingTeam(), vo, true);
                    }
                    else{
                        teamName.getTextBox().setValue(getPlayingTeam().getTeamName());
                    }
                }
            });
            setTitle("Edit team");
        }
        return teamName;
    }

    public VerticalComponent getPlayersPanel() {
        if (playersPanel == null) {
            playersPanel = new VerticalComponent();
        }
        return playersPanel;
    }



    public void addNewPlayer(Member m, String nonMember) {
        PlayingTeamVO upt = new PlayingTeamVO(playingTeam);
        if (m != null) {
            upt.getMembers().add(m.getId());
        }
        else {
            upt.getNonMembers().add(nonMember);
        }

        RTC.getInstance().updateTeam(playingTeam, upt, true);

    }

    private void addNewPlayerComponent(Member m, String mString) {
        PlayerComponent p = new PlayerComponent(this, mString, m);
        players.add(p);
        playersPanel.add(p, new TextLayout());
    }


    public SimplePanelComponent getSuggestBoxHolder() {
        if (suggestBoxHolder == null) {
            suggestBoxHolder = new SimplePanelComponent();
            suggestBoxHolder.add(getSuggestBox(), suggestBoxLayout);
        }
        return suggestBoxHolder;
    }


    public void delete(PlayerComponent pc) {
        PlayingTeamVO upt = new PlayingTeamVO(playingTeam);
        if (pc.getMember() != null) {
            upt.getMembers().remove(pc.getMember().getId());
        }
        else {
            upt.getNonMembers().remove(pc.getPlayerName());
        }
        RTC.getInstance().updateTeam(playingTeam, upt, true);
    }

    private void adjustCommentSize() {
        if (players.size() == 0) {
            getInfoArea().getTextArea().setVisibleLines(1);
        }
        else {
            getInfoArea().getTextArea().setVisibleLines(players.size());
        }
    }


    public FocusManager getFocusManager() {
        return focusManager;
    }


    public PlayingTeam getPlayingTeam() {
        return playingTeam;
    }

    public void setFocus(boolean focus) {
        getSuggestBox().getSuggestBox().setFocus(false);
    }


}